# -*- coding: utf-8 -*-

from celery import Task
from celery import Celery
from celery.registry import tasks
from celery.schedules import crontab

class Work_Task(Task):
    abstract = True

    # def __call__(self,*var1, **var2):
    #     return  self.exec(*var1, **var2)

    def exec(self,*var1, **var2):
        return  self.delay(*var1, **var2).get()


    def on_success(self, retval, task_id, args, kwargs):
        print('task done: {0}'.format(retval))
        return super(Work_Task, self).on_success(retval, task_id, args, kwargs)

    def on_failure(self, exc, task_id, args, kwargs, einfo):
        print('task fail, reason: {0}'.format(exc))
        return super(Work_Task, self).on_failure(exc, task_id, args, kwargs, einfo)



class tasks:

    tasks={}
    crontab=crontab
    def __init__(self,name="tasks",config=None):
        self.config={}
        self.app = Celery(name)
        self.app.Task = Work_Task
        if config is not None:
            self.load_config(config)

    def load_config(self,config):
        self.config=config
        redis='redis://:{password}@{host}:{port}/{db}'.format(**config)
        self.app.conf.result_backend=redis
        self.app.conf.broker_url=redis
        self.app.conf.accept_content = ['json']
        self.app.conf.task_serializer="json"
        self.app.conf.result_serializer="json"
        self.app.conf.task_result_expires=360000
    def set(self,key,value):
        setattr(self.app.conf,key,value)

    def add(self,name,func,base=None):
        if base is None:
            base=Work_Task
        self.tasks[name]=self.app.task(func,base=base)
        return self.tasks[name]

    def worker(self):
        self.app.worker_main()

    def __getattr__(self, name):
        return self.tasks.get(name,None)
    def run(self,name,*var1, **var2):
        t=self.tasks.get(name,None)
        result=None
        if t is not None:
            result=t.delay(*var1, **var2).get()
        return result
    def cron(self,conf):
        from celery.bin.beat import beat
        self.app.conf.beat_schedule=conf
        beat(app=self.app).execute_from_commandline()
